case class HitRecord(
  var p: Vec3,
  var normal: Vec3,
  var t: Double,
  var front_face: Boolean,
  var material: Material
):
  def set_face_normal(r: Ray, outward_normal: Vec3) =
    this.front_face = dot(r.direction, outward_normal) < 0
    this.normal = if front_face then outward_normal else outward_normal * -1.0


trait Hittable:
  def hit(r: Ray, t_min: Double, t_max: Double): Option[HitRecord]